#include "wc3string.h"
#include "Extern_global_Variable.h"

PStringManager GetStringManager()
{
	PStringManager Result;
	if ((*ppStringManager) != NULL)
	{
		Result = (*ppStringManager);
	}
	else
	{
		Result = (PStringManager)Allocate((PtrUInt)sizeof(TStringManager));
		(*Result).TStringManager::TStringManager();
		(*ppStringManager) = Result;
	}
	return Result;
}

PStringRep TStringManager::GetRepresentationFor(PChar AString)
{
	PStringRep Result;
	if (AString == NULL)
	{
		Result = pNullRep;
	}
	else if (!FStorage.Find(AString, Result))
	{
		Result = FStorage.CreateItem(AString);
	}
	return Result;
}

TStringManager::TStringManager()
{
	FStorage.TSHashTable::TSHashTable();
	FStorage.vtable = p_TStringManager_VMT;
}

TStringManager::~TStringManager()
{
	FStorage.~TSHashTable();
}

procedure TRCString::SetRepresentation(PStringRep ARepresentation)
{
	if (FRepresentation != NULL)
	{
		(*FRepresentation).DecRef();
	}

	FRepresentation = ARepresentation;

	if (FRepresentation != NULL)
	{
		(*FRepresentation).IncRef();
	}
}

procedure TRCString::SetContent(PChar AString)
{
	FRepresentation = (PStringRep)(**ppStringManager).GetRepresentationFor(AString);
}

PChar TRCString::GetContent()
{
	PChar Result;
	if (FRepresentation != NULL)
	{
		Result = FRepresentation->HashKeyData.Key;
	}
	else
	{
		Result = NULL;
	}
	return Result;
}

procedure TRCString::Clear()
{
	FRepresentation = NULL;
}

TRCString::TRCString()
{
	//inherited;
	vtable = p_TRCString_VMT;
	FRepresentation = NULL;
}

TRCString::~TRCString()
{
	vtable = p_TRCString_VMT;
	FRepresentation = NULL;
	//inherited;
}

procedure wc3string_Init()
{
	p_TStringManager_VMT = Pointer(GameDll+0x9546D4);
	p_TRCString_VMT = (PRCString)Pointer(GameDll+0x87688C);
	ppStringManager = (PStringManager*)Pointer(GameDll+0xAB7D14);
	pNullRep = (PStringRep)Pointer(GameDll+0xA85E18);

	(*pNullRep).IncRef();
}

void wc3string_main()
{
	wc3main_SubscribeOnInit(&wc3string_Init);
}